package mechanics;

// Used for the timer to function
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

// The timer
import javax.swing.Timer;

/**
 * The LightGuard class regulates the dimmer to get the correct amount of light
 * to the sensors
 * 
 * @version 31-03-2009
 */
public class LightGuard {

	// The percentage that should be added to the dimmer each time an addition
	// is done
	private double addition;

	// The controller to control the dimmer
	private Controller controller;

	// The current amount of light which is read from the sensor
	private int curLightAmount;

	// The maximum amount of light allowed
	private int maxLight;
	// The minimum amount of light allowed
	private int minLight;

	// The last adjustment that needed to be done
	private int preAdjust;
	// The current adjustment that needs to be done
	private int curAdjust;

	// The delay between the checks
	private int delay;

	// The HistoryMaker, used for getting the specified boundaries
	private HistoryMaker hm;

	/**
	 * Constructor loads the controller and prepares the class to begin
	 * 
	 * @param c The controller
	 */
	public LightGuard(Controller c) {
		// Create the HistoryMaker
		this.hm = new HistoryMaker();
		// Load the controller
		controller = c;
		// Set the additon
		addition = 2;
		// Set the delay
		delay = 2000;

		// Start with the dimmer of to ensure a proper functioning guard
		c.setDimmer(0);

		// Start the timer
		ActionListener taskPerformer = new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				run();
			}
		};
		new Timer(delay, taskPerformer).start();
	}

	public void run() {
		// Get the operation mode from the database
		String operation_mode = this.hm.retrieveSetting("operation_mode");
		// Get the desired value of light from the database
		String light_value = this.hm.retrieveSetting("light_value");

		// Set the boundaries of the dimmer
		this.setPreferedLight(Integer.valueOf(light_value), 10);

		// If the operation mode is set to auto, run the guard
		if (operation_mode.equals("automatisch")) {
			this.refresh();
		}
	}

	/**
	 * Sets the boundaries of the dimmer
	 * 
	 * @param value The desired value of light received by the sensor
	 * @param margin The margin, specifies how much the dimmer may be off
	 */
	private void setPreferedLight(int value, int margin) {
		maxLight = value + margin;
		minLight = value - margin;
	}

	/**
	 * Adjusts the dimmer if necessary
	 * 
	 * Records the current adjustment that needs to be done and compares it to
	 * the last one. If they are equal, the dimmer gets adjusted
	 * This is done to eliminate sporadic sensor values
	 */
	private void refresh() {
		// Gets the current amount of light received by the sensor
		curLightAmount = controller.getLight();

		// Sets the previous adjustment
		preAdjust = curAdjust;

		// Gets the value of the dimmer
		double dimmer = controller.getDimmerValue();

		// Checks if the amount of light is outside of the boundaries
		if (curLightAmount < minLight) {
			curAdjust = 1;
		} else if (curLightAmount > maxLight) {
			curAdjust = -1;
		} else {
			curAdjust = 0;
		}

		// If the light was outside of the boundaries two times in a row, the
		// dimmer gets adjusted.
		if (curAdjust == preAdjust && dimmer < 100) {
			controller.setDimmer(dimmer + curAdjust * addition);
		}
	}
}
